import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

// ES 模块中获取 __dirname
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 配置路径
const PROJECT_ROOT = path.resolve(__dirname, '..');
const ASSETS_DIR = path.join(PROJECT_ROOT, 'src/assets');
const SRC_DIR = path.join(PROJECT_ROOT, 'src');
const PUBLIC_DIR = path.join(PROJECT_ROOT, 'public');
const EXTENSIONS_TO_SCAN = ['.vue', '.ts', '.js', '.tsx', '.jsx', '.html', '.css', '.scss', '.less'];

// 图片文件扩展名
const IMAGE_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.ico', '.bmp'];

// 递归获取所有静态资源文件
function getAllAssets(dir, fileList = []) {
  if (!fs.existsSync(dir)) {
    console.log(`⚠️  目录不存在: ${dir}`);
    return fileList;
  }
  
  const files = fs.readdirSync(dir);
  
  files.forEach(file => {
    const filePath = path.join(dir, file);
    const stat = fs.statSync(filePath);
    
    if (stat.isDirectory()) {
      getAllAssets(filePath, fileList);
    } else if (IMAGE_EXTENSIONS.some(ext => file.toLowerCase().endsWith(ext))) {
      fileList.push(filePath);
    }
  });
  
  return fileList;
}

// 递归获取所有源代码文件
function getAllSourceFiles(dir, fileList = []) {
  if (!fs.existsSync(dir)) {
    console.log(`⚠️  目录不存在: ${dir}`);
    return fileList;
  }
  
  const files = fs.readdirSync(dir);
  
  files.forEach(file => {
    const filePath = path.join(dir, file);
    
    // 跳过不需要扫描的目录
    if (fs.statSync(filePath).isDirectory()) {
      if (file === 'node_modules' || file === '.git' || file === 'dist' || file === 'build' || file === 'iot') {
        return;
      }
      getAllSourceFiles(filePath, fileList);
    } else if (EXTENSIONS_TO_SCAN.some(ext => file.endsWith(ext))) {
      fileList.push(filePath);
    }
  });
  
  return fileList;
}

// 检查资源是否被使用
function isAssetUsed(assetPath, sourceFiles) {
  const assetFileName = path.basename(assetPath);
  const assetNameWithoutExt = path.basename(assetPath, path.extname(assetPath));
  
  // 获取相对于 src 目录的路径
  const relativeToSrc = path.relative(SRC_DIR, assetPath).replace(/\\/g, '/');
  // 获取相对于 assets 目录的路径
  const relativeToAssets = path.relative(ASSETS_DIR, assetPath).replace(/\\/g, '/');
  // 获取相对于项目根目录的路径
  const relativeToRoot = path.relative(PROJECT_ROOT, assetPath).replace(/\\/g, '/');
  
  for (const sourceFile of sourceFiles) {
    try {
      const content = fs.readFileSync(sourceFile, 'utf-8');
      
      // 检查多种可能的引用方式
      const checkPatterns = [
        // 1. 完整文件名
        assetFileName,
        // 2. 不带扩展名的文件名
        assetNameWithoutExt,
        // 3. 相对路径（各种形式）
        relativeToSrc,
        relativeToAssets,
        relativeToRoot,
        // 4. 使用 @ 别名的路径
        `@/assets/${relativeToAssets}`,
        `@/${relativeToSrc}`,
        // 5. import 语句中的路径
        `'${relativeToAssets}'`,
        `"${relativeToAssets}"`,
        `'@/assets/${relativeToAssets}'`,
        `"@/assets/${relativeToAssets}"`,
        // 6. CSS 中的 url() 引用
        `url(${assetFileName})`,
        `url('${assetFileName}')`,
        `url("${assetFileName}")`,
        `url(${relativeToAssets})`,
        `url('${relativeToAssets}')`,
        `url("${relativeToAssets}")`,
        // 7. 只检查文件夹名和文件名的组合
        `${path.basename(path.dirname(assetPath))}/${assetFileName}`,
        // 8. React/Vue 中的动态导入
        `require('${relativeToAssets}')`,
        `require("${relativeToAssets}")`,
        `import('${relativeToAssets}')`,
        `import("${relativeToAssets}")`,
      ];
      
      // 检查是否包含任何匹配模式
      if (checkPatterns.some(pattern => content.includes(pattern))) {
        return true;
      }
      
    } catch (error) {
      console.error(`读取文件失败: ${sourceFile}`, error.message);
    }
  }
  
  return false;
}

// 主函数
function findUnusedAssets() {
  console.log('🔍 开始扫描未使用的静态资源...\n');
  
  // 检查目录是否存在
  if (!fs.existsSync(ASSETS_DIR)) {
    console.error(`❌ 静态资源目录不存在: ${ASSETS_DIR}`);
    process.exit(1);
  }
  
  if (!fs.existsSync(SRC_DIR)) {
    console.error(`❌ 源代码目录不存在: ${SRC_DIR}`);
    process.exit(1);
  }
  
  // 获取所有静态资源和源代码文件
  const assetFiles = getAllAssets(ASSETS_DIR);
  const publicAssets = fs.existsSync(PUBLIC_DIR) ? getAllAssets(PUBLIC_DIR) : [];
  const allAssets = [...assetFiles, ...publicAssets];
  const sourceFiles = getAllSourceFiles(SRC_DIR);
  
  // 同时扫描根目录的 HTML 文件
  const rootHtmlFiles = fs.readdirSync(PROJECT_ROOT)
    .filter(file => file.endsWith('.html'))
    .map(file => path.join(PROJECT_ROOT, file));
  sourceFiles.push(...rootHtmlFiles);
  
  console.log(`📊 统计信息:`);
  console.log(`   - 静态资源目录: ${ASSETS_DIR}`);
  console.log(`   - 静态资源总数: ${allAssets.length}`);
  console.log(`   - 源代码文件数: ${sourceFiles.length}\n`);
  
  if (allAssets.length === 0) {
    console.log('⚠️  没有找到任何静态资源文件');
    return;
  }
  
  const unusedAssets = [];
  const usedAssets = [];
  
  console.log('⏳ 正在分析静态资源使用情况...\n');
  
  allAssets.forEach((assetPath, index) => {
    const fileName = path.basename(assetPath);
    const isUsed = isAssetUsed(assetPath, sourceFiles);
    
    if (isUsed) {
      usedAssets.push(assetPath);
      console.log(`✓ [${index + 1}/${allAssets.length}] ${fileName} - 使用中`);
    } else {
      unusedAssets.push(assetPath);
      console.log(`✗ [${index + 1}/${allAssets.length}] ${fileName} - 未使用`);
    }
  });
  
  // 输出结果
  console.log('\n' + '='.repeat(60));
  console.log(`\n📈 扫描完成！`);
  console.log(`   ✅ 使用中的资源: ${usedAssets.length} 个`);
  console.log(`   ❌ 未使用的资源: ${unusedAssets.length} 个`);
  console.log(`   📦 可节省空间: ${calculateSize(unusedAssets)}\n`);
  
  if (unusedAssets.length > 0) {
    console.log('📋 未使用的静态资源详细列表:\n');
    
    // 按文件夹分组
    const groupedAssets = groupByFolder(unusedAssets);
    
    Object.keys(groupedAssets).forEach(folder => {
      console.log(`\n📁 ${folder}:`);
      groupedAssets[folder].forEach((asset, index) => {
        const size = fs.statSync(asset).size;
        console.log(`   ${index + 1}. ${path.basename(asset)} (${formatSize(size)})`);
      });
    });
    
    // 生成脚本目录
    const scriptsDir = path.join(PROJECT_ROOT, 'scripts');
    if (!fs.existsSync(scriptsDir)) {
      fs.mkdirSync(scriptsDir, { recursive: true });
    }
    
    // 生成删除脚本
    const deleteScriptPath = path.join(scriptsDir, 'delete-unused-assets.js');
    const deleteScript = generateDeleteScript(unusedAssets);
    fs.writeFileSync(deleteScriptPath, deleteScript);
    
    // 生成备份脚本
    const backupScriptPath = path.join(scriptsDir, 'backup-unused-assets.js');
    const backupScript = generateBackupScript(unusedAssets);
    fs.writeFileSync(backupScriptPath, backupScript);
    
    // 保存报告
    const reportPath = path.join(scriptsDir, 'unused-assets-report.txt');
    const report = generateReport(allAssets, usedAssets, unusedAssets);
    fs.writeFileSync(reportPath, report, 'utf-8');
    
    console.log('\n' + '='.repeat(60));
    console.log('\n📄 已生成以下文件:');
    console.log(`   1. ${reportPath} - 详细报告`);
    console.log(`   2. ${backupScriptPath} - 备份脚本(推荐先执行)`);
    console.log(`   3. ${deleteScriptPath} - 删除脚本\n`);
    console.log('💡 建议操作步骤:');
    console.log('   1. 先运行 node scripts/backup-unused-assets.js 备份资源');
    console.log('   2. 测试应用是否正常运行');
    console.log('   3. 确认无误后再运行 node scripts/delete-unused-assets.js 删除\n');
    
  } else {
    console.log('🎉 太好了! 所有静态资源都在使用中，没有需要清理的文件。\n');
  }
}

// 生成删除脚本
function generateDeleteScript(unusedAssets) {
  return `import fs from 'fs';
import path from 'path';

// 待删除的静态资源文件路径列表
const unusedAssetPaths = [
${unusedAssets.map(asset => `  '${asset.replace(/\\/g, '\\\\')}'`).join(',\n')}
];

// 使用 async/await 异步处理文件删除
async function deleteUnusedAssets() {
  console.log(\`\\n🚀 开始清理 \${unusedAssetPaths.length} 个未使用的静态资源...\`);

  let successCount = 0;
  let failCount = 0;

  for (const assetPath of unusedAssetPaths) {
    try {
      // 检查文件是否存在
      await fs.promises.access(assetPath, fs.constants.F_OK);

      // 删除文件
      await fs.promises.unlink(assetPath);
      console.log(\`✅ 已删除: \${assetPath}\`);
      successCount++;
    } catch (error) {
      if (error.code === 'ENOENT') {
        console.warn(\`⚠️ 文件不存在，跳过: \${assetPath}\`);
      } else {
        console.error(\`❌ 删除失败: \${assetPath} - 错误: \${error.message}\`);
        failCount++;
      }
    }
  }

  // 最终报告
  console.log('\\n--- 清理完成报告 ---');
  console.log(\`总计路径数: \${unusedAssetPaths.length}\`);
  console.log(\`成功删除: \${successCount} 个文件. 🎉\`);
  if (failCount > 0) {
    console.log(\`失败数量: \${failCount} (请检查错误信息).\`);
  }
  if (successCount === unusedAssetPaths.length) {
    console.log('✨ 所有文件都已成功处理！项目瘦身成功！');
  }
}

// 执行清理函数
deleteUnusedAssets().catch(console.error);
`;
}

// 生成备份脚本
function generateBackupScript(unusedAssets) {
  return `import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 待备份的静态资源文件路径列表
const unusedAssetPaths = [
${unusedAssets.map(asset => `  '${asset.replace(/\\/g, '\\\\')}'`).join(',\n')}
];

// 备份目录
const BACKUP_DIR = path.join(__dirname, '..', 'unused-assets-backup');

// 使用 async/await 异步处理文件备份
async function backupUnusedAssets() {
  console.log(\`\\n🚀 开始备份 \${unusedAssetPaths.length} 个未使用的静态资源...\`);

  // 创建备份目录
  if (!fs.existsSync(BACKUP_DIR)) {
    fs.mkdirSync(BACKUP_DIR, { recursive: true });
  }

  let successCount = 0;
  let failCount = 0;

  for (const assetPath of unusedAssetPaths) {
    try {
      // 检查文件是否存在
      await fs.promises.access(assetPath, fs.constants.F_OK);

      // 计算备份路径
      const relativePath = path.relative(path.join(__dirname, '..'), assetPath);
      const backupPath = path.join(BACKUP_DIR, relativePath);
      const backupDir = path.dirname(backupPath);

      // 创建备份目录
      if (!fs.existsSync(backupDir)) {
        fs.mkdirSync(backupDir, { recursive: true });
      }

      // 复制文件
      await fs.promises.copyFile(assetPath, backupPath);
      console.log(\`✅ 已备份: \${path.basename(assetPath)}\`);
      successCount++;
    } catch (error) {
      if (error.code === 'ENOENT') {
        console.warn(\`⚠️ 文件不存在，跳过: \${assetPath}\`);
      } else {
        console.error(\`❌ 备份失败: \${assetPath} - 错误: \${error.message}\`);
        failCount++;
      }
    }
  }

  // 最终报告
  console.log('\\n--- 备份完成报告 ---');
  console.log(\`总计路径数: \${unusedAssetPaths.length}\`);
  console.log(\`成功备份: \${successCount} 个文件. 🎉\`);
  console.log(\`备份目录: \${BACKUP_DIR}\`);
  if (failCount > 0) {
    console.log(\`失败数量: \${failCount} (请检查错误信息).\`);
  }
}

// 执行备份函数
backupUnusedAssets().catch(console.error);
`;
}

// 生成报告
function generateReport(allAssets, usedAssets, unusedAssets) {
  return `未使用的静态资源报告
生成时间: ${new Date().toLocaleString()}
项目路径: ${PROJECT_ROOT}

统计信息:
========================================
静态资源总数: ${allAssets.length}
使用中的资源: ${usedAssets.length}
未使用的资源: ${unusedAssets.length}
可节省空间: ${calculateSize(unusedAssets)}

未使用的静态资源列表:
========================================
${unusedAssets.map((asset, i) => `${i + 1}. ${asset}`).join('\n')}

使用中的静态资源列表:
========================================
${usedAssets.map((asset, i) => `${i + 1}. ${asset}`).join('\n')}
`;
}

// 按文件夹分组
function groupByFolder(files) {
  const groups = {};
  files.forEach(file => {
    const folder = path.dirname(file);
    if (!groups[folder]) {
      groups[folder] = [];
    }
    groups[folder].push(file);
  });
  return groups;
}

// 计算文件大小
function calculateSize(files) {
  let totalSize = 0;
  files.forEach(file => {
    try {
      totalSize += fs.statSync(file).size;
    } catch (error) {
      // 文件可能不存在，跳过
    }
  });
  return formatSize(totalSize);
}

// 格式化文件大小
function formatSize(bytes) {
  if (bytes < 1024) return bytes + ' B';
  if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB';
  return (bytes / (1024 * 1024)).toFixed(2) + ' MB';
}

// 运行脚本
try {
  findUnusedAssets();
} catch (error) {
  console.error('❌ 错误:', error.message);
  console.error(error.stack);
  process.exit(1);
}